from AIoT_paddle_tools import *
from flask import Flask, request
import cv2
import oss2
import threading
import time
import numpy as np
import requests
import json
import random
# 保存图片的间隔时间
SAVE_INTERVAL = 10

# 开启多少路摄像头
CAM_NUM = 5

# 从TXT里第几个摄像头开始开启
# START_CAM_INDEX = random.randint(0, 50)
START_CAM_INDEX = 0


BREAK_COUNT = 100


# start 申请
# 申请一个人车猪检测的client和预处理序列
seq_pig, client_pig = paddle_client_create('person_pig_car')
# 申请一个工作服检测的client和预处理序列
seq_cls, client_cls = paddle_client_create('suit')
# end 申请

class myThread(threading.Thread):
    def __init__(self, name, rtsp_path, points):
        threading.Thread.__init__(self)
        self.name = name
        self.rtsp_path = rtsp_path
        self.points = points

    def run(self):
        print("开始线程：" + self.name)
        add_new_cam(self.rtsp_path, self.points, self.name)
        print("退出线程：" + self.name)


# 根据视频流获取动态检测
def add_new_cam(rtsp_path, points, pool_id):
    # 创建模型
    mog = cv2.createBackgroundSubtractorMOG2()  # 定义高斯混合模型对象 mog
    gmg = cv2.bgsegm.createBackgroundSubtractorGMG()
    knn = cv2.createBackgroundSubtractorKNN(detectShadows=False)

    # 绘制蒙版

    cap = cv2.VideoCapture(rtsp_path)
    ret, frame = cap.read()
    mask = np.zeros(frame.shape, np.uint8)

    for point in points:
        point[0] = point[0] * frame.shape[1]
        point[1] = point[1] * frame.shape[0]

    points = np.array(points)
    mask = cv2.fillPoly(mask, [points], (255, 255, 255))

    # 初始化计时器用于判断时间
    time_now = time.time()
    

    

    none_frame_count =0
    # cv2.imshow("mask", mask)
    while 1:

        ret, frame = cap.read()
        if frame is None:
            if none_frame_count > BREAK_COUNT:
                break
            continue
        frame_to_save = frame.copy()
        frame_to_show = frame.copy()
        frame = cv2.bitwise_and(frame, mask)

        # 混合高斯模型
        fgmask = mog.apply(frame)  # 使用前面定义的高斯混合模型对象 mog 当前帧的运动目标检测，返回二值图像
        gray_frame = fgmask.copy()
        kernel = np.ones((5, 5), np.uint8)
        gray_frame = cv2.morphologyEx(gray_frame, cv2.MORPH_OPEN, kernel)
        # 返回值： contours，轮廓的坐标。 hierarchy，各个框之间父子关系，不常用。
        contours, hierarchy = cv2.findContours(gray_frame, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

        # 绘制每一个轮廓框到原始图像 frame 中
        for contour in contours:
            if cv2.contourArea(contour) < 1500:  # 计算候选框的面积，如果小于1500，跳过当前候选框
                continue
            (x, y, w, h) = cv2.boundingRect(contour)  # 根据轮廓，得到当前最佳矩形框
            cv2.rectangle(frame_to_show, (x, y), (x + w, y + h), (255, 255, 0), 2)  # 将该矩形框画在当前帧 frame 上

            # 根据时间间隔保存图片
            interval = time.time() - time_now
            if interval > SAVE_INTERVAL:
                time_now = time.time()
                # 保存图片
                current_time_str = int(round(time.time()*1000))
                pic_name = pool_id + '-' + str(current_time_str)

                #cv2.imwrite(filename="image/" + str(s)+ ".jpg", img=frame_to_save)
                # 返回一个json：[{'type': 1, 'rect': [0.2038875379060, 0.3378119468688, 0.08795095744885, 0.38912479501021]},[],[],[]...]
                result, img = paddle_model_person_pig_car(frame_to_save, 2, seq_pig, client_pig, 0.5, False)
                print('----------------------start-------------')
                print(result)
                if len(result):
                    cv2.imwrite(filename="image/" + pic_name + ".jpg", img=frame_to_save)
                    # save oss
                    # upload_img_oss(pic_name)
                    # 判断是是否返回人 继续执行识别工作服
                    for item in result:
                        if (item['type'] == 1):
                            # 图片裁剪
                            image = paddle_get_suit(item, img)
                            # 请求服务器工作服
                            suit = paddle_model_suit(image, 2, seq_cls, client_cls, 0.5)
                            suit_dict = {'suit': suit}
                            item.update(suit_dict)
                            # 拿到结果拼接字符
                    
                    # print('----------------------mid-------------')
                    # send_result_feign(pool_id, result, pic_name)
                    # print('----------------------end-------------')

        # cv2.imshow("gray", gray_frame)
        # cv2.imshow("contours", frame_to_show)  # 显示当前帧
        # cv2.waitKey(30)



app = Flask(__name__)


def send_result_feign(camera_index_code,result,img):
    # 设置要访问的地址（这里是get请求）
    url = 'http://39.107.221.52:10811/info/result'
    # 定一个字典类型
    mapA = {"camera_index_code": camera_index_code, "result": result, "img": img}
    # 把字典转成字符串
    str = json.dumps(mapA)
    # 这里得给设置一个请求格式，不然会返回415
    # header_dict = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Trident/7.0; rv:11.0) like Gecko',"Content-Type": "application/json"}
    header_dict = {"Content-Type": "application/json; charset=utf8"}
    print(str)
    # 直接请求
    r = requests.post(url, data=str, headers=header_dict)
    # 这里是输出了一个字符串
    print(r.text)

# 截取视频流图片并上传oss
def save_rtsp_img(rtsp_path, img_name):
    cap = cv2.VideoCapture(rtsp_path)
    ret, frame = cap.read()
    cv2.imwrite(filename="./image/" + img_name + ".jpg", img=frame)
    auth = oss2.Auth('LTAI4G9UbPy1UCF2LKZ6tk7C', 'mWWWeUEiYKR7UqjbDlL3x1hIQP6usn')
    bucket = oss2.Bucket(auth, 'http://oss-cn-beijing.aliyuncs.com', 'iotdb-bak')
    bucket.put_object_from_file('ai/board/' + img_name + '.jpg', 'image/' + img_name + ".jpg")
    return "success"


# image upload oss
def upload_img_oss(img_name):
    auth = oss2.Auth('LTAI4G9UbPy1UCF2LKZ6tk7C', 'mWWWeUEiYKR7UqjbDlL3x1hIQP6usn')
    bucket = oss2.Bucket(auth, 'http://oss-cn-beijing.aliyuncs.com', 'iotdb-bak')
    bucket.put_object_from_file('ai/board/' + img_name + '.jpg', 'image/' + img_name + ".jpg")
    return "success"

@app.route('/')
def hello_world():
    print(request.args.get('stream'))
    print(request.args.get('camera_index_code'))
    stream = request.args.get('stream')
    camera_index_code = request.args.get('camera_index_code')
    # x = save_rtsp_img(stream, camera_index_code)
    # 动态检测 stream = 视频流 & points = 划定区域
    rtsp_path = stream
    points = [[0, 0], [1, 0], [1, 1], [0, 1]]


    


    list_name = []
    list_num = []
    list_rtsp = []
    with open("双胞胎相机.txt", "r", encoding='utf-8') as f:
        devices = f.readlines()

    for device in devices:
        device_info = device.split("	")
        name = device_info[1].replace("\n", "")
        list_name.append(name)
        list_num.append(device_info[0])

    import requests
    import json

    for i in range(CAM_NUM):
        url = "http://192.168.1.195:8080/cameraPicPoint/camera/" + list_num[START_CAM_INDEX + i]

        res = requests.get(url)
        json_data = json.loads(res.text)
        rtsp = json_data['data']['url']
        list_rtsp.append(rtsp)

    print(list_name)
    print(list_rtsp)

    for index in range(len(list_rtsp)):
        thread = myThread(list_num[START_CAM_INDEX + index], list_rtsp[index], points)
        thread.start()
        time.sleep(10)

    # # myThread(线程名称,stream地址,划定区域)
    # thread = myThread(camera_index_code, rtsp_path, points)
    # thread.start()
    return "success"


if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000, debug=True)

# rtsp = "rtsp://admin:Buchou123@192.168.1.64:554/h264/ch1/main/av_stream"
# points = np.array([(0, 0), (1000, 0), (1000, 1000), (0, 1000)])
# add_new_cam(rtsp, points)
